﻿#include "AliyunOssTask.h"
#include "AliyunOssLink.h"
//#pragma warning(push)
//#pragma warning(disable: 4265)
#include "alibabacloud/oss/OssClient.h"
//#pragma warning(pop)


#include <memory>
#include <fstream>
#include "Misc/FileHelper.h"
#include "Async/TaskGraphInterfaces.h"

using namespace AlibabaCloud::OSS;



#define TASKS_NOT_STARTED TEXT("Tasks not started")
#define WAITING_RESPONSE TEXT("Waiting for server response")
#define CONTENTLENGTH "Content-Length"


static void DownloadCallback(bool bSuccess)
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(1, 20.f, FColor::Cyan, TEXT("Download Task Ok!"));
	}
}

static void DownloadProgress(float Delta)
{
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(1, 20.f, FColor::Cyan, FString::Printf(TEXT("[%f]"), Delta));
	}
}


//Save downloaded data to hard disk or copy it out

static bool SaveDownLoaderBuffer(const AlibabaCloud::OSS::GetObjectOutcome& outCome
	,const FString& LocalObjectFile = "", TArray<uint8>* dataBuffer = nullptr)
{

	if (!outCome.isSuccess())
	{
		return false;
	}

	if (LocalObjectFile.Len() <= 6 && !dataBuffer) 
	{
		//No operation method
		return false;
	}

	const AlibabaCloud::OSS::ObjectMetaData& objData = outCome.result().Metadata();


	long long size = objData.ContentLength();
	if (size <= 1)
	{
		return false;
	}
	
	//bool saveOK = false;
	char* p_dataBuffer = nullptr;
	bool needRelease = false;
	dataBuffer = nullptr;
	if (dataBuffer&&size < MAX_int32) 
	{
		//Only 2GB data can be operated at most
		dataBuffer->Init(0, size);
		p_dataBuffer = (char*)dataBuffer->GetData();
	}
	else 
	{
		needRelease = true;
		p_dataBuffer = new char[size];
	
		//saveOK = true;
	}

	outCome.result().Content()->read(p_dataBuffer, size);

	if (LocalObjectFile.Len() > 6)
	{
		FArchive* Ar = IFileManager::Get().CreateFileWriter(*LocalObjectFile, 0);
		if (Ar)
		{
			Ar->Serialize(p_dataBuffer, size);
			delete Ar;
			//saveOK = true;
		}
	}

	if (needRelease) 
	{
		delete[] p_dataBuffer;
	}

	return true;
}

static std::shared_ptr<std::iostream> GetLocalDataBuffer(const FString& LocalObjectFile , TArray<uint8>* dataBuffer)
{
	std::shared_ptr<std::iostream> content = std::make_shared<std::stringstream>();

	TArray<uint8> tempBuffer;
	tempBuffer.Init(0, 1);
	TArray<uint8>* datePtr = &tempBuffer;
	
	if (LocalObjectFile.Len()>4&&IFileManager::Get().FileExists(*LocalObjectFile))
	{
		FFileHelper::LoadFileToArray(tempBuffer, *LocalObjectFile);
	}
	else
	{
		if (dataBuffer&&dataBuffer->Num()>=1)
		{
			datePtr = dataBuffer;
		}
	}
	content->write((char*)datePtr->GetData(), datePtr->Num());
	return content;
}



FAliyunOssTask::FAliyunOssTask(const FAliyunOssTaskInfo& taskInfo, const FOssCallBackFunction& callback, void* InUserData)
	:m_TaskInfo(taskInfo),inGameThread(false),backMsg(TASKS_NOT_STARTED), taskIsSuccess(false)
	, m_Percent(0.0f), m_callbackEv(callback), m_pUserData(InUserData)
{

}

FAliyunOssTask::FAliyunOssTask(const FAliyunOssTaskInfo& taskInfo)
	: m_TaskInfo(taskInfo),inGameThread(false),  backMsg(TASKS_NOT_STARTED),taskIsSuccess(false)
	, m_Percent(0.0f), m_callbackEv(), m_pUserData(nullptr)
{

}

FAliyunOssTask::~FAliyunOssTask()
{

}

bool FAliyunOssTask::IsSuccess()const 
{
	return taskIsSuccess;
}

FString FAliyunOssTask::GetMsg()const 
{
	return backMsg;
}

FOssTimeTakeNotes FAliyunOssTask::GetTakeNotes()const 
{
	return takeNotes;
}

FString  FAliyunOssTask::GetErrorMsg()const
{
	return errorMeeageBuffer;
}
FString  FAliyunOssTask::GetErrorCode()const
{
	return errorCodeBuffer;
}

//获取文件大小
int64 FAliyunOssTask::GetDataSize()
{
	errorMeeageBuffer = errorCodeBuffer = "";
	std::string bname = TCHAR_TO_UTF8(*m_TaskInfo.bucketName);
	std::string objname = TCHAR_TO_UTF8(*m_TaskInfo.objectKey);
	//获取文件大小
	AlibabaCloud::OSS::OssClient& ossClinet = FOssClient::GetClientRef();
	auto outcome = ossClinet.GetObjectMeta(bname, objname);
	int64 size = -1;
	FString sizeString = "0";
	if (outcome.isSuccess())
	{
		FString out = UTF8_TO_TCHAR(outcome.error().Message().c_str());
		auto metaData = outcome.result().HttpMetaData();
		size = 0;
		if (metaData.count(CONTENTLENGTH)) {

			sizeString = UTF8_TO_TCHAR(metaData[CONTENTLENGTH].c_str());
			size = FCString::Atoi64(*sizeString);
		}
		else {
			errorCodeBuffer = "30000";
			errorMeeageBuffer = "The connection was successful, but the size could not be obtained";
		}
	}
	else 
	{
		errorCodeBuffer = UTF8_TO_TCHAR(outcome.error().Code().c_str());
		errorMeeageBuffer = UTF8_TO_TCHAR(outcome.error().Message().c_str());

	}
	GLog->Log(FString::Printf(TEXT("GetDataSize== %i= str="), size)+ sizeString);
	return size;
}


void FAliyunOssTask::ProgressCallback(size_t increment, int64_t transfered, int64_t total, void* userData)
{
	m_Percent = double(transfered) / (double)total;
	takeNotes.dataSize = total;

	if(inGameThread)OnProgressCallBack();
	//std::cout << "AliOperByURLTaskProgress[" << userData << "] => " <<
	//	increment << " ," << transfered << "," << total << std::endl;
}

void FAliyunOssTask::TaskComplete(bool isSuccess, const FString& errorCode, const FString& errorMessage)
{
	
	backMsg = errorMessage;
	taskIsSuccess = isSuccess;
	
	if (errorCode.Contains("200006") ||
		errorCode.Contains("200007"))
	{
		backMsg = FString(TEXT("网络链接失败，请检测网络后重试\r\nNetwork link failed, please check the network and try again"));
	}

	//callback Must be in the game thread
	if (IsInGameThread())
	{
		m_callbackEv.CallOnComplete(taskIsSuccess, m_pUserData, backMsg);
	}
	else 
	{
		FGraphEventRef TaskRef = FFunctionGraphTask::CreateAndDispatchWhenReady([&]()
		{
			m_callbackEv.CallOnComplete(taskIsSuccess, m_pUserData, backMsg);

		}, TStatId(), nullptr, ENamedThreads::GameThread);


		FTaskGraphInterface::Get().WaitUntilTaskCompletes(TaskRef);
	}
}

void FAliyunOssTask::BindServiceRequest(AlibabaCloud::OSS::ServiceRequest& request)
{

	TransferProgress progressCallback;
	progressCallback.UserData = this;
	progressCallback.Handler = std::bind(&FAliyunOssTask::ProgressCallback, this
		, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);

	request.setTransferProgress(progressCallback);
}

void FAliyunOssTask::OnProgressCallBack()const
{

	checkSlow(IsInGameThread());
	//callback Must be in the game thread
	m_callbackEv.CallOnProgress(m_Percent, m_pUserData);
}


void FAliyunOssTask::TickTask(const float& DeltaTime) 
{
	OnProgressCallBack();
}

void FAliyunOssTask::DoWork()
{
	inGameThread = IsInGameThread();

	if (!inGameThread)
	{
		FOssTaskTickMag::GetTickMag()->AddTask(this);
	}

	switch (m_TaskInfo.handleType)
	{
	case EAliyunOssType::DownloadByObject:
	{
		HandleDownloadByObject();
		break;
	}
	case EAliyunOssType::UploadByObject:
	{
		HandleUploadByObject();
		break;
	}
	
	case EAliyunOssType::UploadStringBuffer:
	{
		HandleBufferDataUploadByObject();
		break;
	}
	default:
	{

	}
	}

	if (!inGameThread)
	{
		FOssTaskTickMag::GetTickMag()->RemoveTask(this);
	}
}

bool FAliyunOssTask::CanAbandon() 
{
	return true;
}


void FAliyunOssTask::GetObjectAsyncCallFunction(
	const OssClient* client
	,const GetObjectRequest& ObjectRequest
	//, const GetObjectOutcome& Outcome
	, const class AlibabaCloud::OSS::Outcome<AlibabaCloud::OSS::OssError, AlibabaCloud::OSS::GetObjectResult>& Outcome
	, const std::shared_ptr<const AsyncCallerContext>& asyncCallerPtr
)
{
	
	taskIsSuccess = Outcome.isSuccess();
	if (taskIsSuccess)
	{
		errorCodeBuffer = errorMeeageBuffer ="";
	}
	else 
	{
		errorCodeBuffer = UTF8_TO_TCHAR(Outcome.error().Code().c_str());
		errorMeeageBuffer = UTF8_TO_TCHAR(Outcome.error().Message().c_str());
	}

	takeNotes.CompleteWork(Outcome.result().Metadata().ContentLength());
	GLog->Log("Down Over");
	waitFor = false;
	//SaveDownLoaderBuffer(Outcome,"D:/downloader/tAsyncCall.zip");
}


void FAliyunOssTask::HandleDownloadByObject()
{
	takeNotes.StartWork();

	std::string bname = TCHAR_TO_UTF8(*m_TaskInfo.bucketName);
	std::string objname = TCHAR_TO_UTF8(*m_TaskInfo.objectKey);
	int64 dataSize = GetDataSize();

	if (dataSize < 0) {

		TaskComplete(false,errorCodeBuffer, errorMeeageBuffer);
	}

	IFileManager& fileManager = IFileManager::Get();
	//获取文件路径
	FString path = FPaths::GetPath(m_TaskInfo.strLocalObjectFilePath);

	if (fileManager.FileExists(*m_TaskInfo.strLocalObjectFilePath))
	{
		if (!fileManager.Delete(*m_TaskInfo.strLocalObjectFilePath))
		{
			errorCodeBuffer = "30000";
			errorMeeageBuffer = "Cannot delete local file!";
			TaskComplete(false, errorCodeBuffer, errorMeeageBuffer);
			return;
		}
	}

	backMsg = WAITING_RESPONSE;


	std::string localPath = TCHAR_TO_UTF8(*m_TaskInfo.strLocalObjectFilePath);
	GetObjectRequest request(bname, objname);
	BindServiceRequest(request);

	request.setResponseStreamFactory([=]() {
		return std::make_shared<std::fstream>(localPath, std::ios_base::out | std::ios_base::trunc | std::ios::binary);
		}
	);
	//std::function<void(const AlibabaCloud::OSS::OssClient*, const GetObjectRequest&, const GetObjectOutcome&, const std::shared_ptr<const AsyncCallerContext>&)> asyncHandler =
		auto  asyncHandler =
	std::bind(&FAliyunOssTask::GetObjectAsyncCallFunction, this
			, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);


	AlibabaCloud::OSS::OssClient& ossClinet = FOssClient::GetClientRef();
	//waitFor = true;
	taskIsSuccess = false;
	waitFor = true;
	ossClinet.GetObjectAsync(request, asyncHandler, nullptr);

	while (waitFor)
	{
		FPlatformProcess::Sleep(1);
	}

	if (m_TaskInfo.LocalObjectDataPtr&& taskIsSuccess)
	{
		FFileHelper::LoadFileToArray(*m_TaskInfo.LocalObjectDataPtr,*m_TaskInfo.strLocalObjectFilePath);
	}


	TaskComplete(taskIsSuccess, errorCodeBuffer, errorMeeageBuffer);

	//AlibabaCloud::OSS::GetObjectOutcome outcome = ossClinet.GetObject(bname, objname,localPath);
	//taskIsSuccess = outcome.isSuccess();
	//takeNotes.CompleteWork(outcome.result().Metadata().ContentLength());
	//if (taskIsSuccess)
	//{
		//taskIsSuccess = SaveDownLoaderBuffer(outcome, m_TaskInfo.strLocalObjectFilePath, m_TaskInfo.LocalObjectDataPtr);
	//}

	//TaskComplete(taskIsSuccess, UTF8_TO_TCHAR(outcome.error().Code().c_str()), UTF8_TO_TCHAR(outcome.error().Message().c_str()));
}

void FAliyunOssTask::HandleUploadByObject()
{
	backMsg = WAITING_RESPONSE;
	std::shared_ptr<std::iostream> content = GetLocalDataBuffer(m_TaskInfo.strLocalObjectFilePath, m_TaskInfo.LocalObjectDataPtr);
	PutObjectRequest request(TCHAR_TO_UTF8(*m_TaskInfo.bucketName), TCHAR_TO_UTF8(*m_TaskInfo.objectKey), content);	
	BindServiceRequest(request);
	takeNotes.StartWork(content->gcount());
	auto outcome = FOssClient::GetClientRef().PutObject(request);
	taskIsSuccess = outcome.isSuccess();
	takeNotes.CompleteWork();
	TaskComplete(taskIsSuccess, UTF8_TO_TCHAR(outcome.error().Code().c_str()), UTF8_TO_TCHAR(outcome.error().Message().c_str()));
}

void FAliyunOssTask::HandleDownloadByURL()
{
	backMsg = WAITING_RESPONSE;
	IFileManager& fileManager = IFileManager::Get();

	if (fileManager.FileExists(*m_TaskInfo.strLocalObjectFilePath))
	{
		if (!fileManager.Delete(*m_TaskInfo.strLocalObjectFilePath))
		{
			TaskComplete(false,"30000","Cannot delete local file!");
			return;
		}
	}

	GetObjectByUrlRequest request(TCHAR_TO_UTF8(*m_TaskInfo.inOssObjectFilePath));
	//BindServiceRequest(request);
	takeNotes.StartWork();
	auto outcome = FOssClient::GetClientRef().GetObjectByUrl(request);
	taskIsSuccess = outcome.isSuccess();
	takeNotes.CompleteWork(outcome.result().Metadata().ContentLength());

	if (taskIsSuccess)
	{
		taskIsSuccess = SaveDownLoaderBuffer(outcome, m_TaskInfo.strLocalObjectFilePath, m_TaskInfo.LocalObjectDataPtr);
	}

	TaskComplete(taskIsSuccess, UTF8_TO_TCHAR(outcome.error().Code().c_str()), UTF8_TO_TCHAR(outcome.error().Message().c_str()));
}

void FAliyunOssTask::HandleUploadByURL()
{
	backMsg = WAITING_RESPONSE;
	std::shared_ptr<std::iostream> content = GetLocalDataBuffer(m_TaskInfo.strLocalObjectFilePath, m_TaskInfo.LocalObjectDataPtr);

	takeNotes.StartWork(content->gcount());
	PutObjectByUrlRequest request(TCHAR_TO_UTF8(*m_TaskInfo.inOssObjectFilePath), content);
	BindServiceRequest(request);
	auto outcome = FOssClient::GetClientRef().PutObjectByUrl(request);
	taskIsSuccess = outcome.isSuccess();
	takeNotes.CompleteWork();

	TaskComplete(taskIsSuccess, UTF8_TO_TCHAR(outcome.error().Code().c_str()), UTF8_TO_TCHAR(outcome.error().Message().c_str()));
}

void FAliyunOssTask::HandleBufferDataUploadByObject() 
{
	std::shared_ptr<std::iostream> content = std::make_shared<std::stringstream>();
	std::string data(TCHAR_TO_UTF8(*m_TaskInfo.strLocalObjectFilePath));
	*content << data;
	PutObjectRequest request(TCHAR_TO_UTF8(*m_TaskInfo.bucketName), TCHAR_TO_UTF8(*m_TaskInfo.objectKey), content);
	ObjectMetaData& MetaData = request.MetaData();
	MetaData.setContentType("application/json");
	takeNotes.StartWork(content->gcount());
	auto outcome = FOssClient::GetClientRef().PutObject(request);
	taskIsSuccess = outcome.isSuccess();
	takeNotes.CompleteWork();
	TaskComplete(taskIsSuccess, UTF8_TO_TCHAR(outcome.error().Code().c_str()), UTF8_TO_TCHAR(outcome.error().Message().c_str()));
}

bool FAliyunOssTask::DoSynchronizationTask(const FAliyunOssTaskInfo& taskInfo,FString* outMsg) 
{
	FAliyunOssTask* task = new FAliyunOssTask(taskInfo);
	task->DoWork();
	if (outMsg) 
	{
		*outMsg = task->GetMsg();
	}
	bool success = task->IsSuccess();
	delete task;
	task = nullptr;
	return success;
}


//******************************************FAliyunOssTaskDeleteObjects********************************


void FAliyunOssTaskDeleteObjects::DoWork()
{
	do
	{
		DeleteObjectsRequest reqDeleteObjects(m_strBucketName);
		uint32 nDeleteFilesNum = m_arrDeleteFiles.Num() > OssObjectsOperNumLimit ? OssObjectsOperNumLimit : m_arrDeleteFiles.Num();
		for (uint32 i = 0; i < nDeleteFilesNum; ++i)
		{
			reqDeleteObjects.addKey(m_arrDeleteFiles[i]);
		}
		auto outcomeDeleteObjects = FOssClient::GetClientRef().DeleteObjects(reqDeleteObjects);
		m_arrDeleteFiles.RemoveAt(0, nDeleteFilesNum);
		if (!outcomeDeleteObjects.isSuccess())
		{
			//failid
		}
	} while (m_arrDeleteFiles.Num() > 0);
}



/********************************FAliyunOssGraphTask*****************************************************************************************/
//
//#include <stdio.h>
//FAliyunOssGraphTask::~FAliyunOssGraphTask()
//{
//
//}
//
//
////void FAliyunOssGraphTask::TickTask(const float& DeltaTime)
////{
////	//OnProgressCallBack();
////}
//
//
//void FAliyunOssGraphTask::DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& CompletionGraphEvent)
//{
//	switch (m_TaskInfo.handleType)
//	{
//	case EAliyunOssType::DownloadByObject:
//	{
//		HandleDownloadByObject();
//		break;
//	}
//	case EAliyunOssType::UploadByObject:
//	{
//		HandleUploadByObject();
//		break;
//	}
//	case EAliyunOssType::DownloadByURL:
//	{
//		HandleDownloadByObject();
//		//HandleDownloadByURL();
//		break;
//	}
//	case EAliyunOssType::UploadByURL:
//	{
//		HandleUploadByURL();
//		break;
//	}
//	case EAliyunOssType::PanoImageUploadObject:
//	{
//		HandlePanoImageUploadByObject();
//		break;
//	}
//	case EAliyunOssType::UploadBufferData:
//	{
//		HandleBufferDataUploadByObject();
//		break;
//	}
//	default:
//	{
//
//	}
//	}
//}
//
//void FAliyunOssGraphTask::CallOnCompleteWithMsg()
//{
//	if (!m_OnCompleteWithMsg.IsBound())
//		return;
//
//	FString message = m_bUpdateIsSuccess ? FString::Printf(TEXT("download Success %s"), *m_TaskInfo.GetOssObjPath())
//		: FString::Printf(TEXT("Failed download %s to %s"), *m_TaskInfo.GetOssObjPath(), *m_TaskInfo.strLocalObjectFilePath);
//
//	if (IsInGameThread())
//	{
//		m_OnCompleteWithMsg.Execute(m_bUpdateIsSuccess, m_pUserData, message);
//	}
//	else
//	{
//		FGraphEventRef TaskRef = FFunctionGraphTask::CreateAndDispatchWhenReady([&]()
//		{
//			m_OnCompleteWithMsg.Execute(m_bUpdateIsSuccess, m_pUserData, m_TaskInfo.strLocalObjectFilePath);
//
//		}, TStatId(), nullptr, ENamedThreads::GameThread);
//
//		FTaskGraphInterface::Get().WaitUntilTaskCompletes(TaskRef);
//	}
//
//}
//
//void FAliyunOssGraphTask::HandleDownloadByObject()
//{
//
//	IFileManager& fileManager = IFileManager::Get();
//	bool bSuccess = false;
//	bool bContinue = true;
//
//	if (FPaths::FileExists(*m_TaskInfo.strLocalObjectFilePath))
//	{
//		GetObjectMetaRequest metaReq(TCHAR_TO_UTF8(*m_TaskInfo.bucketName), TCHAR_TO_UTF8(*m_TaskInfo.objectKey));
//		auto objectMeta = FOssClient::GetClientRef().GetObjectMeta(metaReq);
//		std::string tag = objectMeta.result().ETag();
//		FString strFileHash = FOssHashOper::GetLocalFileHashString(m_TaskInfo.strLocalObjectFilePath);
//		bContinue = !strFileHash.Equals(UTF8_TO_TCHAR(tag.c_str()), ESearchCase::IgnoreCase);
//		if (bContinue)
//		{
//			fileManager.Delete(*m_TaskInfo.strLocalObjectFilePath);
//			bSuccess = false;
//		}
//		else 
//		{
//			bSuccess = true;
//		}
//	}
//	if (bContinue)
//	{
//		GetObjectRequest request(TCHAR_TO_UTF8(*m_TaskInfo.bucketName), TCHAR_TO_UTF8(*m_TaskInfo.objectKey));
//		auto outcome = FOssClient::GetClientRef().GetObject(request);
//		bSuccess = outcome.isSuccess();
//		if (bSuccess)
//		{
//			SaveDownLoaderBuffer(outcome, m_TaskInfo.strLocalObjectFilePath, m_TaskInfo.LocalObjectDataPtr);
//		}
//	}
//
//	m_bUpdateIsSuccess = bSuccess;
//	CallOnCompleteWithMsg();
//}
//
//void FAliyunOssGraphTask::HandleUploadByObject()
//{
//	std::shared_ptr<std::iostream> content = GetLocalDataBuffer(m_TaskInfo.strLocalObjectFilePath, m_TaskInfo.LocalObjectDataPtr);
//	PutObjectRequest request(TCHAR_TO_UTF8(*m_TaskInfo.bucketName), TCHAR_TO_UTF8(*m_TaskInfo.objectKey), content);
//	auto outcome = FOssClient::GetClientRef().PutObject(request);
//	m_bUpdateIsSuccess = outcome.isSuccess();
//
//	//test save to disk
//	//FString path = FPaths::ProjectDir() + "upLoadBuffer/" + m_TaskInfo.objectKey;
//	//FFileHelper::SaveArrayToFile(*m_TaskInfo.LocalObjectDataPtr, *path);
//
//	CallOnCompleteWithMsg();
//}
//
//void FAliyunOssGraphTask::HandleDownloadByURL()
//{
//
//	IFileManager& fileManager = IFileManager::Get();
//	bool bSuccess = false;
//	bool bContinue = true;
//	bool bHaveToUpdate = false;
//	if (FPaths::FileExists(*m_TaskInfo.strLocalObjectFilePath))
//	{
//		GetObjectMetaRequest metaReq(TCHAR_TO_UTF8(*m_TaskInfo.bucketName), TCHAR_TO_UTF8(*m_TaskInfo.objectKey));
//		auto objectMeta = FOssClient::GetClientRef().GetObjectMeta(metaReq);
//		std::string tag = objectMeta.result().ETag();
//		FString strFileHash = FOssHashOper::GetLocalFileHashString(m_TaskInfo.strLocalObjectFilePath);
//		bContinue = !strFileHash.Equals(UTF8_TO_TCHAR(tag.c_str()), ESearchCase::IgnoreCase);
//		if (bContinue)
//		{
//			fileManager.Delete(*m_TaskInfo.strLocalObjectFilePath);
//			bSuccess = false;
//		}
//		else
//		{
//			bSuccess = true;
//
//		}
//	}
//	else 
//	{
//		bHaveToUpdate = true;
//	}
//
//	if (bContinue)
//	{
//		GetObjectByUrlRequest request(TCHAR_TO_UTF8(*m_TaskInfo.inOssObjectFilePath));
//		auto outcome = FOssClient::GetClientRef().GetObjectByUrl(request);
//		bSuccess = outcome.isSuccess();
//		if (bSuccess)
//		{
//			SaveDownLoaderBuffer(outcome, m_TaskInfo.strLocalObjectFilePath, m_TaskInfo.LocalObjectDataPtr);
//		}
//	}
//
//	m_bUpdateIsSuccess = bSuccess;
//	CallOnCompleteWithMsg();
//}
//
//void FAliyunOssGraphTask::HandleUploadByURL()
//{
//	std::shared_ptr<std::iostream> content = GetLocalDataBuffer(m_TaskInfo.strLocalObjectFilePath, m_TaskInfo.LocalObjectDataPtr);
//	PutObjectByUrlRequest request(TCHAR_TO_UTF8(*m_TaskInfo.inOssObjectFilePath), content);
//	auto outcome = FOssClient::GetClientRef().PutObjectByUrl(request);
//	m_bUpdateIsSuccess = outcome.isSuccess();
//	CallOnCompleteWithMsg();
//}
//
//void FAliyunOssGraphTask::HandlePanoImageUploadByObject()
//{
//	HandleUploadByObject();
//
//}
//
//void FAliyunOssGraphTask::HandleBufferDataUploadByObject()
//{
//	std::shared_ptr<std::iostream> content = std::make_shared<std::stringstream>();
//	std::string data(TCHAR_TO_UTF8(*m_TaskInfo.strLocalObjectFilePath));
//	*content << data;
//	PutObjectRequest request(TCHAR_TO_UTF8(*m_TaskInfo.bucketName), TCHAR_TO_UTF8(*m_TaskInfo.objectKey), content);
//	ObjectMetaData& MetaData = request.MetaData();
//	MetaData.setContentType("application/json");
//	auto outcome = FOssClient::GetClientRef().PutObject(request);
//	m_bUpdateIsSuccess = outcome.isSuccess();
//	CallOnCompleteWithMsg();
//}
//
//
///********************************FAliyunOssTaskDeleteObjects*****************************************************************************************/
//
//FAliyunOssTaskDeleteObjects::FAliyunOssTaskDeleteObjects(const FString& InBucketname, const FString& InPrefix) 
//	: m_strBucketName(TCHAR_TO_UTF8(*InBucketname))
//{
//	if (InPrefix.IsEmpty())
//	{
//		return;
//	}
//
//	ListObjectsRequest reqListObjects(m_strBucketName);
//	reqListObjects.setMaxKeys(OssObjectsOperNumLimit);
//	reqListObjects.setPrefix(TCHAR_TO_UTF8(*InPrefix));
//
//	int32 iListObjectsNum = 0;
//	do
//	{
//		auto outcomeListObjects = FOssClient::GetClientRef().ListObjects(reqListObjects);
//		if (outcomeListObjects.isSuccess())
//		{
//			const ObjectSummaryList& objectSummaryList = outcomeListObjects.result().ObjectSummarys();
//			iListObjectsNum = objectSummaryList.size();
//			for (const auto& object : objectSummaryList)
//			{
//				m_arrDeleteFiles.Emplace(object.Key());
//			}
//			if (m_arrDeleteFiles.Num() > 0)
//			{
//				reqListObjects.setMarker(m_arrDeleteFiles.Last());
//			}
//		}
//	} while (OssObjectsOperNumLimit == iListObjectsNum);
//}
//
//FAliyunOssTaskDeleteObjects::FAliyunOssTaskDeleteObjects(const FString& InBucketname, const TArray<FString>& InOssObjectFiles) 
//	: m_strBucketName(TCHAR_TO_UTF8(*InBucketname))
//{
//	for (const FString& strObjectFile : InOssObjectFiles)
//	{
//		m_arrDeleteFiles.Emplace(TCHAR_TO_UTF8(*strObjectFile));
//	}
//}
